/**
 * @brief privateproto 该空间封装与私有协议有关的处理
 * date:2023/12/18 
 * author:Coolio
 */
#ifndef SRC_CACHE_PRIVATEPROTOCOL_H
#define SRC_CACHE_PRIVATEPROTOCOL_H

#include <assert.h>
#include <string>
#include <functional>
#include <sstream>
#include "jsoncpp/json.h"

namespace privateproto {
    #define CACHE_APP_NAME "cache"
    /**
    * 设备通道对象,系统的媒体缓存以该对象作为key索引
    */
    class DeviceChannel {
    public:
        DeviceChannel(const std::string &vhost = "__defaultVhost__",const std::string &appname = "rtp") { _vhost = vhost;_appname = appname;}
        ~DeviceChannel() {}
        bool parse_streamid(const std::string &stream_id);
        bool is_playback() const;
        bool operator < (const DeviceChannel& other) const {
            int bc = _deviceid.compare(other._deviceid);
            if(bc > 0) {
                return false;
            }else if(bc < 0) {
                return true;
            }
            bc = _channelid.compare(other._channelid);
            if(bc > 0) {
                return false;
            }else if(bc < 0) {
                return true;
            }
            //vhost不参与设备通道唯一性维护
            /*bc = _vhost.compare(other._vhost);
            if(bc > 0) {
                return false;
            }else if(bc < 0) {
                return true;
            }*/
            return false;
        }
        std::string GenStreamId() const{
            std::ostringstream ss;
            if(_partcount == 3) {
                ss << _deviceid;
                ss << "_";
                ss << _channelid;
                ss << "_";
                ss << _ssrc;
            }else{
                ss << _schema;
                ss << "_";
                ss << _deviceid;
                ss << "_";
                ss << _channelid;
                ss << "_";
                ss << _ssrc;
            }
            
            return ss.str();
        }
        std::string GenStreamId2() const{
            std::ostringstream ss;
            if(_partcount == 3) {
                ss << _deviceid;
                ss << ":";
                ss << _channelid;
                ss << ":";
                ss << _ssrc;
            }else{
                ss << _schema;
                ss << ":";
                ss << _deviceid;
                ss << ":";
                ss << _channelid;
                ss << ":";
                ss << _ssrc;
            }
            return ss.str();
        }
        std::string ToString() const{
            std::ostringstream ss;
            ss << "[";
            ss << _schema;
            ss << "_";
            ss << _deviceid;
            ss << "_";
            ss << _channelid;
            ss << "_";
            ss << _ssrc;
            ss << "]";
            return ss.str();
        }
        
        Json::Value ToJson() const{
            Json::Value body;
            body["vhost"] = _vhost;
            body["app"] = _appname;
            body["deviceid"] = _deviceid;
            body["channelid"] = _channelid;
            return body;
        }
    public:
        std::string _vhost;
        std::string _appname;
        std::string _schema;
        std::string _deviceid;
        std::string _channelid;
        std::string _ssrc;
        int _partcount;
    };

    /**
     * 从stream_id中判断是否是回放流,针对是否是回放流做不同的处理,如回放流做缓存,但其他流不需要
     */
    bool CheckPlayBackStreamFromStreamId(const std::string stream_id); 
    
    /**
     * 从stream_id中判断是否是缓存流
     */
    bool CheckCacheStreamFromStreamId(const std::string stream_id); 
    /**
     * 从stream_id中提取设备和通道号,检查是否有该设备通道的缓存,如果有再进一步确认开始时间和结束时间
     */
    void CheckCacheHit(const std::string stream_id, time_t starttime, time_t endtime,std::function<void(bool ,const std::string ,const std::string )> cb);
    void CloseCacheSubscriber(const std::string stream_id);
    /**
     * 根据流的id(携带cache关键字)来操作流的发送行为(暂停/恢复,倍速切换)
     */
    void ControlCacheStream(const std::string stream_id, const std::string command, const float scale,std::function<void(bool controlsuccess)> cb);
    
    /**
     * 关闭缓存流的订阅者发送
     */
    void CloseCacheStreamSubscriber(const std::string stream_id);

    /**
    * 判断timestamp是否是比prev_timestamp更新的时间戳
    */
    bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp);
    
    
    /**
    * 判断timestamp是否相比较于prev_timestamp存在跳变(毫秒)
    */
    bool IsBrokenTimestamp(uint32_t timestamp, uint32_t prev_timestamp);

}
#endif
